<?php
/**
 *  * 系统-受国家计算机软件著作权保护 - !
 * =========================================================
 * Copy right 2018-2025 成都海之心科技有限公司, 保留所有权利。
 * ----------------------------------------------
 * 官方网址: http://www.ohyu.cn
 * 这不是一个自由软件！在未得到官方有效许可的前提下禁止对程序代码进行修改和使用。
 * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
 * =========================================================
 * User: ohyueo
 * Date: 2023/2/2
 * Time: 21:08
 */
namespace app\handler;

use app\api\models\EscortUserList;
use app\handler\MoneyLogHandler;
use app\handler\YuyueListmsgHandler;
use think\facade\Db;
use Yansongda\Pay\Pay;
use think\facade\Log;

class MoneyRefundHandler
{
    /**用户余额退款**/
    public function yuerefund($data){
        $money=$data['money'];
        $uid=$data['uid'];
        $msg=$data['msg'];
        $webtype=$data['webtype'];
        $httit='用户'.$msg;
        if($webtype==2){
            $httit='后台'.$msg;
        }
        //余额退款
        $user=EscortUserList::find($uid);
        $user->money+=$money;
        $user->save();
        // 会员卡消费记录
        $text = $httit;
        MoneyLogHandler::add($user,$money,1,1,$text);

        $this->upteordstatus($data);
    }

    /**
     * @title 用户退款
     * @description 前后端统一的退款接口
     * @author ohyueo
     * @url app/handler/userrefund
     * @param array $order 订单数据
     * @param int $uid 用户id
     * @param int $type 1公众号支付 2网页支付 3小程序支付
     * @param string $msg 退款说明
     * @param int $htst 退款类型 1用户前端退款 2后台退款
     * @param int $style 退款类型 1整个订单退款 2单个场地退款
     * @param int $omid 单个场地订单id
     * @return array
     */
    public function userrefund($order,$data){
        $money=$order['paymo'];
        $pay_order=$order['pay_order'];
        $id=$order['id'];
        $paymo=$order['paymo']*100;
        $uid=$order['uid'];

        $type=$data['type'];
        $msg=$data['msg'];
        $style=$data['style'];
        $webtype=$data['webtype'];
        $dataid=$data['dataid'];

        $rearr=[
            'id'=>$id,
            'money'=>$money,
            'pay_order'=>$pay_order,
            'uid'=>$uid,
            'msg'=>$msg,
            'style'=>$style,
            'webtype'=>$webtype,
            'dataid'=>$dataid,
            'payst' => $order['payst'],
        ];
        $res=$this->setrefunmsg($rearr);
        var_dump($res);exit;
        exit;

        //判断是否已经被退款了
        if($style==1 && $order['status']==5){
            return array('status'=>0,'msg'=>'订单已退款，请勿重复操作');exit;
        }
        //如果订单退款金额  大于等于了  付款金额 就组织退款  不能在退了
        $tuimo=Db::name('schoolcatering_order_orderlist')->where('id',$id)->value('tuimo');
        if($tuimo>=$order['paymo']){
            
            return array('status'=>0,'msg'=>'退款金额异常，可能存在重复退款，请联系技术人员排查');exit;
        }

        //如果是余额支付的  那么退款也需要退到余额里面去
        if($order['payst']==2){
            $rearr=[
                'id'=>$id,
                'money'=>$money,
                'pay_order'=>$pay_order,
                'uid'=>$uid,
                'msg'=>$msg,
                'style'=>$style,
                'webtype'=>$webtype,
                'dataid'=>$dataid,
                'payst' => $order['payst'],
            ];
            $this->yuerefund($rearr);//余额退款
            return array('status'=>200,'msg'=>'退款成功-余额退款');exit;
        }

        //如果没有退款金额  那么直接修改订单状态为已退款
        if($order['paymo']==0 && $order['money']==0){
            //无需支付的订单  退款  直接修改订单状态
            Db::name('schoolcatering_order_orderlist')->where('id',$id)->update(['status'=>5]);
            YuyueListmsgHandler::add('用户退款完成-无退款金额',$id,5,'已退款');
            //通知模板消息  公众号
            //$data=['uid'=>$uid,'id'=>$id,'tit'=>'您的订单已退款成功-无退款金额','money'=>$money];
            //event('SendYuyueMessage', ['data'=>$data,'type'=>3]);//通知预约成功
            return array('status'=>200,'msg'=>'退款成功-无退款金额');exit;
            //return $this->message('退款成功-无退款金额', []);
        }

        $orderx = [
            'out_trade_no' => $pay_order,
            'out_refund_no' => $pay_order,
            'total_fee' => $paymo,
            'refund_fee' => $paymo,
            'refund_desc' => '用户主动退款',
        ];
        //改为先在平台把退款订单存入后  在实际在微信退款
        //开启事务 正常退金额
        Db::startTrans();
        try {
            
            //集成修改 订单状态  订单记录  收入记录  //排查问题注意
            $dataarr=[
                'webtype'=>$webtype,
                'id'=>$id,
                'uid'=>$uid,
                'msg'=>$msg,
                'money'=>$money,
                'pay_order'=>$pay_order,
                'style'=>$style,
                'dataid'=>$dataid,
                'payst' => $order['payst'],
            ];
            $this->upteordstatus($dataarr);

            if($type==1){
                $conf=$this->wxh5conf();
                $wechat = Pay::wechat($conf);
                $result = $wechat->refund($orderx);
            }else if($type==2){
                $conf=$this->wxwapconf();
                $wechat = Pay::wechat($conf);
                $result = $wechat->refund($orderx);
            }else{
                $conf=$this->wxconf();
                $wechat = Pay::wechat($conf);
                $orderx['type']= 'miniapp';
                $result = $wechat->refund($orderx);
            }
            if($result['return_code']=='SUCCESS'){
                $codes=200;
                $msg='退款成功';
            }else{
                $codes=0;
                $msg='退款失败，请联系客服'.$result['return_msg'];
                Log::info('退款失败，请联系客服'.$result['return_msg']);
            }
            if($result['return_code']=='SUCCESS'){
                $codes=1;
                $msg='退款成功';
            }else{
                $codes=0;
                $msg='退款失败，请联系客服'.$result['return_msg'];
                Log::info('退款失败，请联系客服'.$result['return_msg']);
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            $error=$e->getMessage();
            $msg='退款失败,请联系客服:'.$error;
            Log::info($msg);
            $codes=0;
            // 回滚事务
            Db::rollback();
        }
        return array('status'=>$codes,'msg'=>$msg);exit;
    }
    /**
     * @title 退款修改订单  订单记录 和  收入记录
     * @description 前后端统一的退款接口
     * @author ohyueo
     * @url app/handler/upteordstatus
     * @param int $style 退款类型 1整个订单退款 2单个退款
     * @param int $id 订单id
     * @param int $uid 用户id
     * @param string $msg 备注
     * @money int $money 金额
     * @return array
     */
    protected function upteordstatus($data){
        $style=$data['style']; //退款类型 1整个订单退款 2单个订单退款
        $id=$data['id']; //订单id
        $uid=$data['uid']; //用户id
        $msg=$data['msg']; //备注
        $money=$data['money']; //金额
        $pay_order=$data['pay_order']; //支付订单号
        $webtype=$data['webtype']; //操作类型 1前端 2后台
        $dataid=$data['dataid']; //数据id
        if($webtype==2){
            $tit='后台';
        }else{
            $tit='用户';
        }
        
        //区分单个订单和整个订单退款
        if($style==1){ //整个订单退款
            //修改订单状态为  已退款  修改支付状态为2 已退款
            Db::name('schoolcatering_order_orderlist')->where('id',$id)->update(['status'=>5,'tuimo'=>$money]);//修改订单状态为  已退款  修改支付状态为2 已退款
            Db::name('schoolcatering_order_orderdata')->where('orderid',$id)->update(['status'=>5,'tuimo'=>$money]);
            YuyueListmsgHandler::add('用户退款完成',$id,5,'已退款');
            //修改收入记录 为退款成功
            Db::name('schoolcatering_pay_income')->where('orderid',$id)->update(['status'=>2,'tuimo'=>$money,'tuitime'=>gettime()]);
            
            $this->setrefunmsg($data);
            
        }else if($style==2){ //单个子订单退款
            //如果该订单下面的所有订单  都已经退款了  那么修改主订单为已退款
            $istui=Db::name('venues_order_multiple')->where('order_id',$id)->where('status','<',5)->count();
            if($istui<=1){ //主订单
                Db::name('yuyue_order')->where('id',$id)->update(['status'=>5,'msg'=>$msg]);//修改订单状态为  已退款  修改支付状态为2 已退款
                Db::name('venues_order_multiple')->where('id',$omid)->update(['status'=>5,'tuimo'=>$money,'msg'=>$msg]);
                Db::name('yuyue_order')->where('id',$id)->inc('tuimo',$money)->update();//重新计算主订单退款金额
                YuyueListmsgHandler::add($tit.'：'.$msg,$id,5,'场地订单已退款:'.$money);
                //支付记录改成已退款
                if($pay_order){
                    Db::name('payorder')->where('ordernum',$pay_order)->inc('tuimo',$money)->update();
                    Db::name('payorder')->where('ordernum',$pay_order)->update(['status'=>2]);
                }

                //退款记录 str
                $userid=$uid;//默认就是普通用户
                if($htst==2){ //如果是后台则读取 后台用户id
                    $userid=0;
                    $username = session('admin_name');
                    if($username){
                        $userid = Db::name('admin')->where('username', $username)->value('id');
                    }
                }
                $payid=Db::name('payorder')->where('ordernum',$pay_order)->value('id');
                MoneyLogHandler::refundmsg($tit.'退款：'.$msg,$id,$uid,$payid,$htst,$userid,$tit,$money);
                //退款记录  end

                //收入记录 增加退款金额  改成已退款
                Db::name('venues_income')->where('orderid',$id)->where('type',1)->inc('tuimo',$money)->update();
                Db::name('venues_income')->where('orderid',$id)->where('type',1)->update(['status'=>2,'tuitime'=>gettime()]);

                //有积分 则积分也退
                $integral=Db::name('yuyue_order')->where('id',$id)->value('integral');//如果有积分 那么积分也要退
                if($integral){
                    $user=UserList::find($uid);
                    if($integral){
                        $user->integral+=$integral;
                        $user->save();
                        //积分记录
                        $text = $tit.'：'.$msg;
                        MoneyLogHandler::addint($user,$integral,1,1,$text);
                    }
                }

                //通知要放最后  不然有问题会影响前面的退款逻辑
                $data=['uid'=>$uid,'id'=>$id,'money'=>$money,'mobile'=>$mobile,'yuyue_id'=>$yuyue_id,'tit'=>'订单退款提醒','msg'=>'您的场地订单已'.$tit];
                event('SendYuyueMessage', ['data'=>$data,'type'=>3]);//退款预约成功
            }
            else{ //单个场地订单
                Db::name('venues_order_multiple')->where('id',$omid)->update(['status'=>5,'tuimo'=>$money,'msg'=>$msg]);
                Db::name('yuyue_order')->where('id',$id)->inc('tuimo',$money)->update();//重新计算主订单退款金额
                YuyueListmsgHandler::add($tit.'：'.$msg,$id,5,'场地订单已退款:'.$money);

                //退款记录  str
                $userid=$uid;//默认就是普通用户
                if($htst==2){ //如果是后台则读取 后台用户id
                    $userid=0;
                    $username = session('admin_name');
                    if($username){
                        $userid = Db::name('admin')->where('username', $username)->value('id');
                    }
                }
                $payid=Db::name('payorder')->where('ordernum',$pay_order)->value('id');
                MoneyLogHandler::refundmsg($tit.'：'.$msg,$id,$uid,$payid,$htst,$userid,$tit,$money);
                //退款记录  end

                //收入路 增加已退款金额
                Db::name('venues_income')->where('orderid',$id)->where('type',1)->inc('tuimo',$money)->update();
                //通知要放最后  不然有问题会影响前面的退款逻辑
                $data=['uid'=>$uid,'id'=>$id,'money'=>$money,'mobile'=>$mobile,'yuyue_id'=>$yuyue_id,'tit'=>'订单退款提醒','msg'=>'您的场地订单已'.$tit];
                event('SendYuyueMessage', ['data'=>$data,'type'=>3]);//退款预约成功
            }
        }
    }
    //增加退款记录
    protected function setrefunmsg($data){
        $pay_order=$data['pay_order'];
        $style=$data['style']; //退款类型 1整个订单退款 2单个订单退款
        $id=$data['id']; //订单id
        $uid=$data['uid']; //用户id
        $msg=$data['msg']; //备注
        $money=$data['money']; //金额
        $webtype=$data['webtype']; //操作类型 1前端 2后台
        $dataid=$data['dataid']; //数据id
        if($webtype==2){
            $tit='后台';
        }else{
            $tit='用户';
        }
        
        if($style==1)
        {
            //支付记录改成已退款 并且是微信支付
            if($pay_order && $data['payst']==1){  //如果有订单号  不是会员卡支付的订单  则修改订单和加入退款记录
                Db::name('schoolcatering_pay_payorder')->where('ordernum',$pay_order)->update(['status'=>2,'tuimo'=>$money]);
                //退款记录 str  这里是有订单号的 是微信支付的订单
                $userid=$uid;//默认就是普通用户
                if($webtype==2){ //如果是后台则读取 后台用户id
                    $userid=0;
                    $username = session('admin_name');
                    if($username){
                        $userid = Db::name('schoolcatering_admin')->where('username', $username)->value('id');
                    }
                }
                $payid=Db::name('schoolcatering_pay_payorder')->where('ordernum',$pay_order)->value('id');
                $redata=['title'=>$tit.'：'.$msg,'payid'=>$payid,'orderid'=>$id,'uid'=>$uid,'usertype'=>$webtype,'userid'=>$userid,'tuimsg'=>$msg];
                MoneyLogHandler::refundmsg($redata);
                //退款记录  end
            }else if($data['payst']==2){
                //如果是余额支付  并且是退整个订单
                //退款记录
                $userid=$uid;//默认就是普通用户
                if($webtype==2){ //如果是后台则读取 后台用户id
                    $userid=0;
                    $username = session('admin_name');
                    if($username){
                        $userid = Db::name('schoolcatering_admin')->where('username', $username)->value('id');
                    }
                }
                $redata=['title'=>$tit.'：'.$msg,'payid'=>0,'orderid'=>$id,'uid'=>$uid,'usertype'=>$webtype,'userid'=>$userid,'tuimsg'=>$msg];
                MoneyLogHandler::refundmsg($redata);
            }
        }

        //通知要放最后  不然有问题会影响前面的退款逻辑
        //$data=['uid'=>$uid,'id'=>$id,'money'=>$money,'mobile'=>$mobile,'yuyue_id'=>$yuyue_id,'tit'=>'订单退款提醒','msg'=>'您的订单已'.$tit];
        //event('SendYuyueMessage', ['data'=>$data,'type'=>3]);//退款预约成功
        
    }
    protected function wxh5conf(){
        $wxconfig = [
            'app_id' => config('-wxsite.wx_gzh_appid'), // 公众号 APPID
            'mch_id' => config('-wxsite.wx_xcx_mchid'),
            'key' => config('-wxsite.wx_xcx_mchkey'),
            'cert_client' => './cert/apiclient_cert.pem', // optional，退款等情况时用到
            'cert_key' => './cert/apiclient_key.pem',// optional，退款等情况时用到
            'notify_url' => config('-appsite.app_domainname').'resource/Payco/h5wxnotify',
            'return_url' => config('-appsite.app_domainname').'index/index/pay',
        ];
        return $wxconfig;
    }

    protected function wxwapconf(){
        $wxconfig = [
            'app_id' => config('-wxsite.wx_wap_appid'), // APPID
            'mch_id' => config('-wxsite.wx_xcx_mchid'),
            'key' => config('-wxsite.wx_xcx_mchkey'),
            'cert_client' => './cert/apiclient_cert.pem', // optional，退款等情况时用到
            'cert_key' => './cert/apiclient_key.pem',// optional，退款等情况时用到
            'notify_url' => config('-appsite.app_domainname').'resource/Payco/h5wxnotify',
            'return_url' => config('-appsite.app_domainname').'index/index/pay',
        ];
        return $wxconfig;
    }

    protected function wxconf(){
        $wxconfig = [
            'miniapp_id' => config('-wxsite.wx_xcx_appid'), // 小程序 APPID
            'mch_id' => config('-wxsite.wx_xcx_mchid'),
            'key' => config('-wxsite.wx_xcx_mchkey'),
            'cert_client' => './cert/apiclient_cert.pem', // optional，退款等情况时用到
            'cert_key' => './cert/apiclient_key.pem',// optional，退款等情况时用到
            'notify_url' => config('-appsite.app_domainname').'resource/Payco/xcxwxnotify',
            'return_url' => config('-appsite.app_domainname').'index/index/pay',
        ];
        return $wxconfig;
    }
}